package main

import (
	"encoding/json"
	"fmt"
	"github.com/Kong/go-pdk"
	"io/ioutil"
	"log"
	"net/http"
	"strings"
)

type Config struct {
	ApiKey  string
	ApiHost string
	Legion  string
	Debug   bool
}

func New() interface{} {
	return &Config{}
}

func (conf Config) Access(kong *pdk.PDK) {
	sub := getHeader(kong, "X-Authenticated-Userid")
	dom := conf.Legion
	obj, _ := kong.Request.GetPath()
	act, _ := kong.Request.GetMethod()
	if conf.Debug {
		kong.Response.SetHeader("x-rbac", fmt.Sprintf("sub: %s, dom: %s, obj: %s, act: %s, result: %s", sub, dom, obj, act, "ok"))
	}
	if sub != "" {
		if sub != "admin" {
			sub = "normal"
		}
		res, err := conf.Check(sub, dom, obj, act)
		if err != nil {
			kong.Response.SetHeader("x-rbac-err", err.Error())
			return
		}
		ok := res["data"]
		if conf.Debug {
			kong.Response.SetHeader("x-rbac-ok", fmt.Sprintf("res: %s", ok.(bool)))
		}
		if !ok.(bool) {
			kong.Response.Ask("kong.response.exit", 403, "Permission Deny")
		}
	}
}

func (conf Config) Check(sub string, dom string, obj string, act string) (map[string]interface{}, error) {
	body := make(map[string]string)
	body["sub"] = sub
	body["tenant"] = dom
	body["obj"] = obj
	body["act"] = act
	marshal, err := json.Marshal(body)
	if err != nil {
		log.Panic(err)
		return nil, err
	}
	response, err := http.Post(conf.ApiHost, "application/json", strings.NewReader(string(marshal)))
	if err != nil {
		log.Panic(err)
		return nil, err
	}
	defer response.Body.Close()
	permission, err := ioutil.ReadAll(response.Body)
	if err != nil {
		log.Panic(err)
		return nil, err
	}
	res := make(map[string]interface{})
	err = json.Unmarshal(permission, &res)
	if err != nil {
		log.Panic(err)
		return nil, err
	}
	return res, nil
}

func getHeader(kong *pdk.PDK, name string) string {
	value, err := kong.Request.GetHeader(name)
	if err != nil {
		kong.Log.Err(err.Error())
	}
	return value
}
